<!DOCTYPE html>
<html>
  <head>
  <meta http-equiv="content-type" content="text/html; charset=utf-8">
  <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport">
  <meta name="description" content="刘清政">
  <meta name="keyword" content="hexo-theme">
  
    <link rel="shortcut icon" href="/css/images/logo.png">
  
  <title>
    
      python/Django框架/15-Django高级之-cookie与session | Justin-刘清政的博客
    
  </title>
  <link href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
  <link href="//cdnjs.cloudflare.com/ajax/libs/nprogress/0.2.0/nprogress.min.css" rel="stylesheet">
  <link href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/tomorrow.min.css" rel="stylesheet">
  
<link rel="stylesheet" href="/css/style.css">

  
    
<link rel="stylesheet" href="/css/plugins/gitment.css">

  
  <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
  <script src="//cdnjs.cloudflare.com/ajax/libs/geopattern/1.2.3/js/geopattern.min.js"></script>
  <script src="//cdnjs.cloudflare.com/ajax/libs/nprogress/0.2.0/nprogress.min.js"></script>
  
    
<script src="/js/qrious.js"></script>

  
  
    
<script src="/js/gitment.js"></script>

  
  

  
<meta name="generator" content="Hexo 4.2.0"></head>
<div class="wechat-share">
  <img src="/css/images/logo.png" />
</div>

  <body>
    <header class="header fixed-header">
  <div class="header-container">
    <a class="home-link" href="/">
      <div class="logo"></div>
      <span>Justin-刘清政的博客</span>
    </a>
    <ul class="right-list">
      
        <li class="list-item">
          
            <a href="/" class="item-link">主页</a>
          
        </li>
      
        <li class="list-item">
          
            <a href="/tags/" class="item-link">标签</a>
          
        </li>
      
        <li class="list-item">
          
            <a href="/archives/" class="item-link">归档</a>
          
        </li>
      
        <li class="list-item">
          
            <a href="/about/" class="item-link">关于我</a>
          
        </li>
      
    </ul>
    <div class="menu">
      <span class="icon-bar"></span>
      <span class="icon-bar"></span>
      <span class="icon-bar"></span>
    </div>
    <div class="menu-mask">
      <ul class="menu-list">
        
          <li class="menu-item">
            
              <a href="/" class="menu-link">主页</a>
            
          </li>
        
          <li class="menu-item">
            
              <a href="/tags/" class="menu-link">标签</a>
            
          </li>
        
          <li class="menu-item">
            
              <a href="/archives/" class="menu-link">归档</a>
            
          </li>
        
          <li class="menu-item">
            
              <a href="/about/" class="menu-link">关于我</a>
            
          </li>
        
      </ul>
    </div>
  </div>
</header>

    <div id="article-banner">
  <h2>python/Django框架/15-Django高级之-cookie与session</h2>



  <p class="post-date">2020-09-24</p>
    <!-- 不蒜子统计 -->
    <span id="busuanzi_container_page_pv" style='display:none' class="">
        <i class="icon-smile icon"></i> 阅读数：<span id="busuanzi_value_page_pv"></span>次
    </span>
  <div class="arrow-down">
    <a href="javascript:;"></a>
  </div>
</div>
<main class="app-body flex-box">
  <!-- Article START -->
  <article class="post-article">
    <section class="markdown-content"><h2 id="1-会话跟踪技术"><a href="#1-会话跟踪技术" class="headerlink" title="1 会话跟踪技术"></a><strong>1 会话跟踪技术</strong></h2><h3 id="什么是会话跟踪"><a href="#什么是会话跟踪" class="headerlink" title="什么是会话跟踪"></a><strong>什么是会话跟踪</strong></h3><p>我们需要先了解一下什么是会话！可以把会话理解为客户端与服务器之间的一次会晤，在一次会晤中可能会包含多次请求和响应。例如你给10086打个电话，你就是客户端，而10086服务人员就是服务器了。从双方接通电话那一刻起，会话就开始了，到某一方挂断电话表示会话结束。在通话过程中，你会向10086发出多个请求，那么这多个请求都在一个会话中。<br>在Web中，客户向某一服务器发出第一个请求开始，会话就开始了，直到客户关闭了浏览器会话结束。 </p>
<p>在一个会话的多个请求中共享数据，这就是会话跟踪技术。例如在一个会话中的请求如下：  请求银行主页； </p>
<ul>
<li>请求登录（请求参数是用户名和密码）；</li>
<li>请求转账（请求参数与转账相关的数据）； </li>
<li>请求信誉卡还款（请求参数与还款相关的数据）。 </li>
</ul>
<p>在这上会话中当前用户信息必须在这个会话中共享的，因为登录的是张三，那么在转账和还款时一定是相对张三的转账和还款！这就说明我们必须在一个会话过程中有共享数据的能力。</p>
<h3 id="会话路径技术使用Cookie或session完成"><a href="#会话路径技术使用Cookie或session完成" class="headerlink" title="会话路径技术使用Cookie或session完成"></a>会话路径技术使用Cookie或session完成</h3><p>我们知道HTTP协议是无状态协议，也就是说每个请求都是独立的！无法记录前一次请求的状态。但HTTP协议中可以使用Cookie来完成会话跟踪！在Web开发中，使用session来完成会话跟踪，session底层依赖Cookie技术。</p>
<h2 id="2-cookie介绍"><a href="#2-cookie介绍" class="headerlink" title="2 cookie介绍"></a><strong>2 cookie介绍</strong></h2><p><strong>cookie的由来</strong></p>
<p> 大家都知道HTTP协议是无状态的 </p>
<p>无状态的意思是每次请求都是独立的，它的执行情况和结果与前面的请求和之后的请求都无直接关系，它不会受前面的请求响应情况直接影响，也不会直接影响后面的请求响应情况。</p>
<p>一句有意思的话来描述就是人生只如初见，对服务器来说，每次的请求都是全新的。</p>
<p>状态可以理解为客户端和服务器在某次会话中产生的数据，那无状态的就以为这些数据不会被保留。会话中产生的数据又是我们需要保存的，也就是说要“保持状态”。因此Cookie就是在这样一个场景下诞生。</p>
<h3 id="什么是cookie"><a href="#什么是cookie" class="headerlink" title="什么是cookie"></a>什么是cookie</h3><p>其实Cookie是key-value结构，类似于一个python中的字典。随着服务器端的响应发送给客户端浏览器。然后客户端浏览器会把Cookie保存起来，当下一次再访问服务器时把Cookie再发送给服务器。 Cookie是由服务器创建，然后通过响应发送给客户端的一个键值对。客户端会保存Cookie，并会标注出Cookie的来源（哪个服务器的Cookie）。当客户端向服务器发出请求时会把所有这个服务器Cookie包含在请求中发送给服务器，这样服务器就可以识别客户端了！</p>
<h3 id="cookie的原理"><a href="#cookie的原理" class="headerlink" title="cookie的原理"></a>cookie的原理</h3><p>cookie的工作原理是：由服务器产生内容，浏览器收到请求后保存在本地；当浏览器再次访问时，浏览器会自动带上Cookie，这样服务器就能通过Cookie的内容来判断这个是“谁”了。</p>
<h3 id="Cookie规范"><a href="#Cookie规范" class="headerlink" title="Cookie规范"></a>Cookie规范</h3><ul>
<li>Cookie大小上限为4KB； </li>
<li>一个服务器最多在客户端浏览器上保存20个Cookie； </li>
<li>一个浏览器最多保存300个Cookie； </li>
</ul>
<p>上面的数据只是HTTP的Cookie规范，但在浏览器大战的今天，一些浏览器为了打败对手，为了展现自己的能力起见，可能对Cookie规范“扩展”了一些，例如每个Cookie的大小为8KB，最多可保存500个Cookie等！但也不会出现把你硬盘占满的可能！<br>注意，不同浏览器之间是不共享Cookie的。也就是说在你使用IE访问服务器时，服务器会把Cookie发给IE，然后由IE保存起来，当你在使用FireFox访问服务器时，不可能把IE保存的Cookie发送给服务器。</p>
<h3 id="Cookie的覆盖"><a href="#Cookie的覆盖" class="headerlink" title="Cookie的覆盖"></a>Cookie的覆盖</h3><p> 如果服务器端发送重复的Cookie那么会覆盖原有的Cookie，例如客户端的第一个请求服务器端发送的Cookie是：Set-Cookie: a=A；第二请求服务器端发送的是：Set-Cookie: a=AA，那么客户端只留下一个Cookie，即：a=AA。</p>
<h3 id="在浏览器中查看cookie"><a href="#在浏览器中查看cookie" class="headerlink" title="在浏览器中查看cookie"></a>在浏览器中查看cookie</h3><p>浏览器中按F12，点network—cookies就能看到</p>
<h2 id="Django中操作Cookie"><a href="#Django中操作Cookie" class="headerlink" title="Django中操作Cookie"></a>Django中操作Cookie</h2><h3 id="获取Cookie"><a href="#获取Cookie" class="headerlink" title="获取Cookie"></a>获取Cookie</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">request.COOKIES[<span class="string">'key'</span>]</span><br><span class="line">request.get_signed_cookie(key, default=RAISE_ERROR, salt=<span class="string">''</span>, max_age=<span class="literal">None</span>)</span><br></pre></td></tr></table></figure>

<p>参数：</p>
<ul>
<li>default: 默认值</li>
<li>salt: 加密盐</li>
<li>max_age: 后台控制过期时间</li>
</ul>
<h3 id="设置Cookie"><a href="#设置Cookie" class="headerlink" title="设置Cookie"></a>设置Cookie</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">rep = HttpResponse(...)</span><br><span class="line">rep ＝ render(request, ...)</span><br><span class="line"></span><br><span class="line">rep.set_cookie(key,value)</span><br><span class="line">rep.set_signed_cookie(key,value,salt=<span class="string">'加密盐'</span>)</span><br></pre></td></tr></table></figure>

<p>参数：</p>
<ul>
<li>key, 键</li>
<li>value=’’, 值</li>
<li>max_age=None, 超时时间 cookie需要延续的时间（以秒为单位）如果参数是\ None`` ，这个cookie会延续到浏览器关闭为止</li>
<li>expires=None, 超时时间(IE requires expires, so set it if hasn’t been already.)</li>
<li>path=’/‘, Cookie生效的路径，/ 表示根路径，特殊的：根路径的cookie可以被任何url的页面访问，浏览器只会把cookie回传给带有该路径的页面，这样可以避免将cookie传给站点中的其他的应用。</li>
<li>domain=None, Cookie生效的域名 你可用这个参数来构造一个跨站cookie。如，  domain=”.example.com”所构造的cookie对下面这些站点都是可读的：<a href="http://www.example.com" target="_blank" rel="noopener">www.example.com</a> 、  www2.example.com 和an.other.sub.domain.example.com 。如果该参数设置为 None  ，cookie只能由设置它的站点读取</li>
<li>secure=False, 浏览器将通过HTTPS来回传cookie</li>
<li>httponly=False 只能http协议传输，无法被JavaScript获取（不是绝对，底层抓包可以获取到也可以被覆盖）</li>
</ul>
<h3 id="删除Cookie"><a href="#删除Cookie" class="headerlink" title="删除Cookie"></a>删除Cookie</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">logout</span><span class="params">(request)</span>:</span></span><br><span class="line">    rep = redirect(<span class="string">"/login/"</span>)</span><br><span class="line">    rep.delete_cookie(<span class="string">"user"</span>)  <span class="comment"># 删除用户浏览器上之前设置的usercookie值</span></span><br><span class="line">    <span class="keyword">return</span> rep</span><br></pre></td></tr></table></figure>

<h3 id="Cookie版登录校验"><a href="#Cookie版登录校验" class="headerlink" title="Cookie版登录校验"></a>Cookie版登录校验</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">login_auth</span><span class="params">(func)</span>:</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">inner</span><span class="params">(request,*args,**kwargs)</span>:</span></span><br><span class="line">        next_url=request.get_full_path()</span><br><span class="line">        <span class="keyword">if</span> request.COOKIES.get(<span class="string">'is_login'</span>):</span><br><span class="line">            <span class="keyword">return</span> func(request,*args,**kwargs)</span><br><span class="line">        <span class="keyword">else</span>:</span><br><span class="line">            <span class="keyword">return</span> redirect(<span class="string">'cookie_login/?next=%s'</span>%next_url)</span><br><span class="line">    <span class="keyword">return</span> inner</span><br><span class="line"><span class="meta">@login_auth</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">cookie_order</span><span class="params">(request)</span>:</span></span><br><span class="line">    <span class="keyword">return</span> HttpResponse(<span class="string">'我是订单页面'</span>)</span><br><span class="line"><span class="meta">@login_auth</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">cookie_index</span><span class="params">(request)</span>:</span></span><br><span class="line">    name=request.COOKIES.get(<span class="string">'username'</span>)</span><br><span class="line">    <span class="keyword">return</span> render(request,<span class="string">'cookie_index.html'</span>,&#123;<span class="string">'name'</span>:name&#125;)</span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">cookie_login</span><span class="params">(request)</span>:</span></span><br><span class="line">    <span class="keyword">if</span> request.method ==<span class="string">'POST'</span>:</span><br><span class="line">        next_url=request.GET.get(<span class="string">'next'</span>)</span><br><span class="line">        name=request.POST.get(<span class="string">'name'</span>)</span><br><span class="line">        password=request.POST.get(<span class="string">'password'</span>)</span><br><span class="line">        <span class="keyword">if</span> name == <span class="string">'lqz'</span> <span class="keyword">and</span> password == <span class="string">'123'</span>:</span><br><span class="line">            <span class="keyword">import</span> datetime</span><br><span class="line">            now=datetime.datetime.now().strftime(<span class="string">'%Y-%m-%d %X'</span>)</span><br><span class="line">            print(now)</span><br><span class="line">            obj=redirect(next_url)</span><br><span class="line">            obj.set_cookie(<span class="string">'is_login'</span>,<span class="literal">True</span>)</span><br><span class="line">            obj.set_cookie(<span class="string">'username'</span>,name)</span><br><span class="line">            obj.set_cookie(<span class="string">'login_time'</span>,now)</span><br><span class="line">            <span class="keyword">return</span> obj</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> render(request, <span class="string">'cookie_login.html'</span>)</span><br></pre></td></tr></table></figure>

<h2 id="Session"><a href="#Session" class="headerlink" title="Session"></a>Session</h2><h3 id="Session的由来"><a href="#Session的由来" class="headerlink" title="Session的由来"></a>Session的由来</h3><p>Cookie虽然在一定程度上解决了“保持状态”的需求，但是由于Cookie本身最大支持4096字节，以及Cookie本身保存在客户端，可能被拦截或窃取，因此就需要有一种新的东西，它能支持更多的字节，并且他保存在服务器，有较高的安全性。这就是Session。</p>
<p>问题来了，基于HTTP协议的无状态特征，服务器根本就不知道访问者是“谁”。那么上述的Cookie就起到桥接的作用。</p>
<p>我们可以给每个客户端的Cookie分配一个唯一的id，这样用户在访问时，通过Cookie，服务器就知道来的人是“谁”。然后我们再根据不同的Cookie的id，在服务器上保存一段时间的私密资料，如“账号密码”等等。</p>
<p>总结而言：Cookie弥补了HTTP无状态的不足，让服务器知道来的人是“谁”；但是Cookie以文本的形式保存在本地，自身安全性较差；所以我们就通过Cookie识别不同的用户，对应的在Session里保存私密的信息以及超过4096字节的文本。</p>
<p>另外，上述所说的Cookie和Session其实是共通性的东西，不限于语言和框架。</p>
<p><img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1gj6rmwmekdj315w0jkq6j.jpg" alt="image-20200928230826583"></p>
<h2 id="Django中Session相关方法"><a href="#Django中Session相关方法" class="headerlink" title="Django中Session相关方法"></a>Django中Session相关方法</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 获取、设置、删除Session中数据</span></span><br><span class="line">request.session[<span class="string">'k1'</span>]</span><br><span class="line">request.session.get(<span class="string">'k1'</span>,<span class="literal">None</span>)</span><br><span class="line">request.session[<span class="string">'k1'</span>] = <span class="number">123</span></span><br><span class="line">request.session.setdefault(<span class="string">'k1'</span>,<span class="number">123</span>) <span class="comment"># 存在则不设置</span></span><br><span class="line"><span class="keyword">del</span> request.session[<span class="string">'k1'</span>]</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 所有 键、值、键值对</span></span><br><span class="line">request.session.keys()</span><br><span class="line">request.session.values()</span><br><span class="line">request.session.items()</span><br><span class="line">request.session.iterkeys()</span><br><span class="line">request.session.itervalues()</span><br><span class="line">request.session.iteritems()</span><br><span class="line"></span><br><span class="line"><span class="comment"># 会话session的key</span></span><br><span class="line">request.session.session_key</span><br><span class="line"></span><br><span class="line"><span class="comment"># 将所有Session失效日期小于当前日期的数据删除</span></span><br><span class="line">request.session.clear_expired()</span><br><span class="line"></span><br><span class="line"><span class="comment"># 检查会话session的key在数据库中是否存在</span></span><br><span class="line">request.session.exists(<span class="string">"session_key"</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 删除当前会话的所有Session数据(只删数据库)</span></span><br><span class="line">request.session.delete()</span><br><span class="line">　　</span><br><span class="line"><span class="comment"># 删除当前的会话数据并删除会话的Cookie（数据库和cookie都删）。</span></span><br><span class="line">request.session.flush() </span><br><span class="line">    这用于确保前面的会话数据不可以再次被用户的浏览器访问</span><br><span class="line">    例如，django.contrib.auth.logout() 函数中就会调用它。</span><br><span class="line"></span><br><span class="line"><span class="comment"># 设置会话Session和Cookie的超时时间</span></span><br><span class="line">request.session.set_expiry(value)</span><br><span class="line">    * 如果value是个整数，session会在些秒数后失效。</span><br><span class="line">    * 如果value是个datatime或timedelta，session就会在这个时间后失效。</span><br><span class="line">    * 如果value是<span class="number">0</span>,用户关闭浏览器session就会失效。</span><br><span class="line">    * 如果value是<span class="literal">None</span>,session会依赖全局session失效策略。</span><br></pre></td></tr></table></figure>

<p>Django中使用session时，做的事：</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 生成随机字符串</span></span><br><span class="line"><span class="comment"># 写浏览器cookie -&gt; session_id: 随机字符串</span></span><br><span class="line"><span class="comment"># 写到服务端session：</span></span><br><span class="line">    <span class="comment"># &#123;</span></span><br><span class="line">    <span class="comment">#     "随机字符串": &#123;'user':'alex'&#125;</span></span><br><span class="line">    <span class="comment"># &#125;</span></span><br></pre></td></tr></table></figure>

<h2 id="Django中的Session配置"><a href="#Django中的Session配置" class="headerlink" title="Django中的Session配置"></a>Django中的Session配置</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="number">1.</span> 数据库Session</span><br><span class="line">SESSION_ENGINE = <span class="string">'django.contrib.sessions.backends.db'</span>   <span class="comment"># 引擎（默认）</span></span><br><span class="line"></span><br><span class="line"><span class="number">2.</span> 缓存Session</span><br><span class="line">SESSION_ENGINE = <span class="string">'django.contrib.sessions.backends.cache'</span>  <span class="comment"># 引擎</span></span><br><span class="line">SESSION_CACHE_ALIAS = <span class="string">'default'</span>                            <span class="comment"># 使用的缓存别名（默认内存缓存，也可以是memcache），此处别名依赖缓存的设置</span></span><br><span class="line"></span><br><span class="line"><span class="number">3.</span> 文件Session</span><br><span class="line">SESSION_ENGINE = <span class="string">'django.contrib.sessions.backends.file'</span>    <span class="comment"># 引擎</span></span><br><span class="line">SESSION_FILE_PATH = <span class="literal">None</span>                                    <span class="comment"># 缓存文件路径，如果为None，则使用tempfile模块获取一个临时地址tempfile.gettempdir() </span></span><br><span class="line"></span><br><span class="line"><span class="number">4.</span> 缓存+数据库</span><br><span class="line">SESSION_ENGINE = <span class="string">'django.contrib.sessions.backends.cached_db'</span>        <span class="comment"># 引擎</span></span><br><span class="line"></span><br><span class="line"><span class="number">5.</span> 加密Cookie Session</span><br><span class="line">SESSION_ENGINE = <span class="string">'django.contrib.sessions.backends.signed_cookies'</span>   <span class="comment"># 引擎</span></span><br><span class="line"></span><br><span class="line">其他公用设置项：</span><br><span class="line">SESSION_COOKIE_NAME ＝ <span class="string">"sessionid"</span>                       <span class="comment"># Session的cookie保存在浏览器上时的key，即：sessionid＝随机字符串（默认）</span></span><br><span class="line">SESSION_COOKIE_PATH ＝ <span class="string">"/"</span>                               <span class="comment"># Session的cookie保存的路径（默认）</span></span><br><span class="line">SESSION_COOKIE_DOMAIN = <span class="literal">None</span>                             <span class="comment"># Session的cookie保存的域名（默认）</span></span><br><span class="line">SESSION_COOKIE_SECURE = <span class="literal">False</span>                            <span class="comment"># 是否Https传输cookie（默认）</span></span><br><span class="line">SESSION_COOKIE_HTTPONLY = <span class="literal">True</span>                           <span class="comment"># 是否Session的cookie只支持http传输（默认）</span></span><br><span class="line">SESSION_COOKIE_AGE = <span class="number">1209600</span>                             <span class="comment"># Session的cookie失效日期（2周）（默认）</span></span><br><span class="line">SESSION_EXPIRE_AT_BROWSER_CLOSE = <span class="literal">False</span>                  <span class="comment"># 是否关闭浏览器使得Session过期（默认）</span></span><br><span class="line">SESSION_SAVE_EVERY_REQUEST = <span class="literal">False</span>                       <span class="comment"># 是否每次请求都保存Session，默认修改之后才保存（默认）</span></span><br></pre></td></tr></table></figure>

<p><strong>思考，如果第二个人再次再同一个浏览器上登录，django-session表会怎样？</strong></p>
<h2 id="CBV中加装饰器"><a href="#CBV中加装饰器" class="headerlink" title="CBV中加装饰器"></a>CBV中加装饰器</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> django <span class="keyword">import</span> views</span><br><span class="line"><span class="keyword">from</span> django.utils.decorators <span class="keyword">import</span> method_decorator</span><br><span class="line"><span class="comment"># @method_decorator(login_auth,name='get')</span></span><br><span class="line"><span class="comment"># @method_decorator(login_auth,name='post')</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">UserList</span><span class="params">(views.View)</span>:</span></span><br><span class="line">    <span class="comment"># @method_decorator(login_auth)</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">dispatch</span><span class="params">(self, request, *args, **kwargs)</span>:</span></span><br><span class="line">        obj=super().dispatch(request, *args, **kwargs)</span><br><span class="line">        <span class="keyword">return</span> obj</span><br><span class="line"></span><br><span class="line"><span class="meta">    @method_decorator(login_auth)</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">get</span><span class="params">(self,request)</span>:</span></span><br><span class="line">        <span class="keyword">return</span> HttpResponse(<span class="string">'我是用户列表'</span>)</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">post</span><span class="params">(self,request)</span>:</span></span><br><span class="line">        <span class="keyword">return</span> HttpResponse(<span class="string">'我是用户列表'</span>)</span><br></pre></td></tr></table></figure></section>
    <!-- Tags START -->
    
    <!-- Tags END -->
    <!-- NAV START -->
    
  <div class="nav-container">
    <!-- reverse left and right to put prev and next in a more logic postition -->
    
      <a class="nav-left" href="/python/Django%E6%A1%86%E6%9E%B6/8-%E6%A8%A1%E5%9E%8B%E5%B1%82-%E5%8D%95%E8%A1%A8%E6%93%8D%E4%BD%9C/">
        <span class="nav-arrow">← </span>
        
          python/Django框架/8-模型层-单表操作
        
      </a>
    
    
      <a class="nav-right" href="/python/Django%E6%A1%86%E6%9E%B6/14-Django%E9%AB%98%E7%BA%A7%E4%B9%8B-forms%E7%BB%84%E4%BB%B6/">
        
          python/Django框架/14-Django高级之-forms组件
        
        <span class="nav-arrow"> →</span>
      </a>
    
  </div>

    <!-- NAV END -->
    <!-- 打赏 START -->
    
      <div class="money-like">
        <div class="reward-btn">
          赏
          <span class="money-code">
            <span class="alipay-code">
              <div class="code-image"></div>
              <b>使用支付宝打赏</b>
            </span>
            <span class="wechat-code">
              <div class="code-image"></div>
              <b>使用微信打赏</b>
            </span>
          </span>
        </div>
        <p class="notice">点击上方按钮,请我喝杯咖啡！</p>
      </div>
    
    <!-- 打赏 END -->
    <!-- 二维码 START -->
    
      <div class="qrcode">
        <canvas id="share-qrcode"></canvas>
        <p class="notice">扫描二维码，分享此文章</p>
      </div>
    
    <!-- 二维码 END -->
    
      <!-- Gitment START -->
      <div id="comments"></div>
      <!-- Gitment END -->
    
  </article>
  <!-- Article END -->
  <!-- Catalog START -->
  
    <aside class="catalog-container">
  <div class="toc-main">
  <!-- 不蒜子统计 -->
    <strong class="toc-title">目录</strong>
    
      <ol class="toc-nav"><li class="toc-nav-item toc-nav-level-2"><a class="toc-nav-link" href="#1-会话跟踪技术"><span class="toc-nav-text">1 会话跟踪技术</span></a><ol class="toc-nav-child"><li class="toc-nav-item toc-nav-level-3"><a class="toc-nav-link" href="#什么是会话跟踪"><span class="toc-nav-text">什么是会话跟踪</span></a></li><li class="toc-nav-item toc-nav-level-3"><a class="toc-nav-link" href="#会话路径技术使用Cookie或session完成"><span class="toc-nav-text">会话路径技术使用Cookie或session完成</span></a></li></ol></li><li class="toc-nav-item toc-nav-level-2"><a class="toc-nav-link" href="#2-cookie介绍"><span class="toc-nav-text">2 cookie介绍</span></a><ol class="toc-nav-child"><li class="toc-nav-item toc-nav-level-3"><a class="toc-nav-link" href="#什么是cookie"><span class="toc-nav-text">什么是cookie</span></a></li><li class="toc-nav-item toc-nav-level-3"><a class="toc-nav-link" href="#cookie的原理"><span class="toc-nav-text">cookie的原理</span></a></li><li class="toc-nav-item toc-nav-level-3"><a class="toc-nav-link" href="#Cookie规范"><span class="toc-nav-text">Cookie规范</span></a></li><li class="toc-nav-item toc-nav-level-3"><a class="toc-nav-link" href="#Cookie的覆盖"><span class="toc-nav-text">Cookie的覆盖</span></a></li><li class="toc-nav-item toc-nav-level-3"><a class="toc-nav-link" href="#在浏览器中查看cookie"><span class="toc-nav-text">在浏览器中查看cookie</span></a></li></ol></li><li class="toc-nav-item toc-nav-level-2"><a class="toc-nav-link" href="#Django中操作Cookie"><span class="toc-nav-text">Django中操作Cookie</span></a><ol class="toc-nav-child"><li class="toc-nav-item toc-nav-level-3"><a class="toc-nav-link" href="#获取Cookie"><span class="toc-nav-text">获取Cookie</span></a></li><li class="toc-nav-item toc-nav-level-3"><a class="toc-nav-link" href="#设置Cookie"><span class="toc-nav-text">设置Cookie</span></a></li><li class="toc-nav-item toc-nav-level-3"><a class="toc-nav-link" href="#删除Cookie"><span class="toc-nav-text">删除Cookie</span></a></li><li class="toc-nav-item toc-nav-level-3"><a class="toc-nav-link" href="#Cookie版登录校验"><span class="toc-nav-text">Cookie版登录校验</span></a></li></ol></li><li class="toc-nav-item toc-nav-level-2"><a class="toc-nav-link" href="#Session"><span class="toc-nav-text">Session</span></a><ol class="toc-nav-child"><li class="toc-nav-item toc-nav-level-3"><a class="toc-nav-link" href="#Session的由来"><span class="toc-nav-text">Session的由来</span></a></li></ol></li><li class="toc-nav-item toc-nav-level-2"><a class="toc-nav-link" href="#Django中Session相关方法"><span class="toc-nav-text">Django中Session相关方法</span></a></li><li class="toc-nav-item toc-nav-level-2"><a class="toc-nav-link" href="#Django中的Session配置"><span class="toc-nav-text">Django中的Session配置</span></a></li><li class="toc-nav-item toc-nav-level-2"><a class="toc-nav-link" href="#CBV中加装饰器"><span class="toc-nav-text">CBV中加装饰器</span></a></li></ol>
    
  </div>
</aside>
  
  <!-- Catalog END -->
</main>

<script>
  (function () {
    var url = 'http://www.liuqingzheng.top/python/Django框架/15-Django高级之-cookie与session/';
    var banner = ''
    if (banner !== '' && banner !== 'undefined' && banner !== 'null') {
      $('#article-banner').css({
        'background-image': 'url(' + banner + ')'
      })
    } else {
      $('#article-banner').geopattern(url)
    }
    $('.header').removeClass('fixed-header')

    // error image
    $(".markdown-content img").on('error', function() {
      $(this).attr('src', 'http://file.muyutech.com/error-img.png')
      $(this).css({
        'cursor': 'default'
      })
    })

    // zoom image
    $(".markdown-content img").on('click', function() {
      var src = $(this).attr('src')
      if (src !== 'http://file.muyutech.com/error-img.png') {
        var imageW = $(this).width()
        var imageH = $(this).height()

        var zoom = ($(window).width() * 0.95 / imageW).toFixed(2)
        zoom = zoom < 1 ? 1 : zoom
        zoom = zoom > 2 ? 2 : zoom
        var transY = (($(window).height() - imageH) / 2).toFixed(2)

        $('body').append('<div class="image-view-wrap"><div class="image-view-inner"><img src="'+ src +'" /></div></div>')
        $('.image-view-wrap').addClass('wrap-active')
        $('.image-view-wrap img').css({
          'width': `${imageW}`,
          'transform': `translate3d(0, ${transY}px, 0) scale3d(${zoom}, ${zoom}, 1)`
        })
        $('html').css('overflow', 'hidden')

        $('.image-view-wrap').on('click', function() {
          $(this).remove()
          $('html').attr('style', '')
        })
      }
    })
  })();
</script>


  <script>
    var qr = new QRious({
      element: document.getElementById('share-qrcode'),
      value: document.location.href
    });
  </script>



  <script>
    var gitmentConfig = "liuqingzheng";
    if (gitmentConfig !== 'undefined') {
      var gitment = new Gitment({
        id: "python/Django框架/15-Django高级之-cookie与session",
        owner: "liuqingzheng",
        repo: "FuckBlog",
        oauth: {
          client_id: "32a4076431cf39d0ecea",
          client_secret: "94484bd79b3346a949acb2fda3c8a76ce16990c6"
        },
        theme: {
          render(state, instance) {
            const container = document.createElement('div')
            container.lang = "en-US"
            container.className = 'gitment-container gitment-root-container'
            container.appendChild(instance.renderHeader(state, instance))
            container.appendChild(instance.renderEditor(state, instance))
            container.appendChild(instance.renderComments(state, instance))
            container.appendChild(instance.renderFooter(state, instance))
            return container;
          }
        }
      })
      gitment.render(document.getElementById('comments'))
    }
  </script>




    <div class="scroll-top">
  <span class="arrow-icon"></span>
</div>
    <footer class="app-footer">
<!-- 不蒜子统计 -->
<span id="busuanzi_container_site_pv">
     本站总访问量<span id="busuanzi_value_site_pv"></span>次
</span>
<span class="post-meta-divider">|</span>
<span id="busuanzi_container_site_uv" style='display:none'>
     本站访客数<span id="busuanzi_value_site_uv"></span>人
</span>
<script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>



  <p class="copyright">
    &copy; 2021 | Proudly powered by <a href="https://www.cnblogs.com/xiaoyuanqujing" target="_blank">小猿取经</a>
    <br>
    Theme by <a href="https://www.cnblogs.com/xiaoyuanqujing" target="_blank" rel="noopener">小猿取经</a>
  </p>
</footer>

<script>
  function async(u, c) {
    var d = document, t = 'script',
      o = d.createElement(t),
      s = d.getElementsByTagName(t)[0];
    o.src = u;
    if (c) { o.addEventListener('load', function (e) { c(null, e); }, false); }
    s.parentNode.insertBefore(o, s);
  }
</script>
<script>
  async("//cdnjs.cloudflare.com/ajax/libs/fastclick/1.0.6/fastclick.min.js", function(){
    FastClick.attach(document.body);
  })
</script>

<script>
  var hasLine = 'true';
  async("//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js", function(){
    $('figure pre').each(function(i, block) {
      var figure = $(this).parents('figure');
      if (hasLine === 'false') {
        figure.find('.gutter').hide();
      }
      var lang = figure.attr('class').split(' ')[1] || 'code';
      var codeHtml = $(this).html();
      var codeTag = document.createElement('code');
      codeTag.className = lang;
      codeTag.innerHTML = codeHtml;
      $(this).attr('class', '').empty().html(codeTag);
      figure.attr('data-lang', lang.toUpperCase());
      hljs.highlightBlock(block);
    });
  })
</script>





<!-- Baidu Tongji -->

<script>
    var _baId = 'c5fd96eee1193585be191f318c3fa725';
    // Originial
    var _hmt = _hmt || [];
    (function() {
      var hm = document.createElement("script");
      hm.src = "//hm.baidu.com/hm.js?" + _baId;
      var s = document.getElementsByTagName("script")[0];
      s.parentNode.insertBefore(hm, s);
    })();
</script>


<script src="/js/script.js"></script>


<script src="/js/search.js"></script>


<script src="/js/load.js"></script>



  <span class="local-search local-search-google local-search-plugin" style="right: 50px;top: 70px;;position:absolute;z-index:2;">
      <input type="search" placeholder="站内搜索" id="local-search-input" class="local-search-input-cls" style="">
      <div id="local-search-result" class="local-search-result-cls"></div>
  </span>


  </body>
</html>